﻿using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Kay.BaseLibrary.Helpers
{
    /// <summary>
    /// 使用系统提供的 DLL 来操作文件
    /// </summary>
    public static class IniHelper
    {
        /// <summary>
        /// 获取 INI 文件里某个字段对应的值
        /// </summary>
        /// <param name="section">标记信息</param>
        /// <param name="key">键</param>
        /// <param name="defValue">键对应的默认值</param>
        /// <param name="retValue">键对应的值</param>
        /// <param name="size">缓冲区大小</param>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        [DllImport("kernel32")]
        public static extern int GetPrivateProfileString(string section, string key, string defValue, StringBuilder retValue, int size, string filePath);

        /// <summary>
        /// 写入 INI 文件某个键值
        /// </summary>
        /// <param name="section">标记信息</param>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        [DllImport("kernel32")]
        public static extern long WritePrivateProfileString(string section, string key, string value, string filePath);

        /// <summary>
        /// 获取 INI 文件某个键值
        /// </summary>
        /// <param name="section">标记信息</param>
        /// <param name="key">键</param>
        /// <param name="filePath">文件路径</param>
        /// <param name="defValue">默认值</param>
        /// <param name="size">缓冲区大小</param>
        /// <returns>获取到的值，如果值不存在则返回默认值</returns>
        public static string GetIniValue(string section, string key, string filePath, string defValue = null, int size = 255)
        {
            StringBuilder sb = new StringBuilder(size);
            GetPrivateProfileString(section, key, defValue, sb, size, filePath);
            return Convert.ToString(sb);
        }

        /// <summary>
        /// 设置 INI 文件某个键值
        /// </summary>
        /// <param name="section">标记信息</param>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="filePath">文件路径</param>
        public static void SetIniValue(string section, string key, string value, string filePath)
        {
            WritePrivateProfileString(section, key, value, filePath);
        }

        /// <summary>
        /// 判断一个ini文件中有多少个节
        /// </summary>
        /// <param name="lpszReturnBuffer">指向一个缓冲区，用来保存返回的所有节名</param>
        /// <param name="nSize">参数lpszReturnBuffer的大小</param>
        /// <param name="lpFileName">文件名，若该ini文件与程序在同一个目录下</param>
        /// <returns>复制的字节数</returns>
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileSectionNamesA(byte[] lpszReturnBuffer, int nSize, string lpFileName);

        /// <summary>
        /// 读取所有的section
        /// </summary>
        /// <returns>section集合</returns>
        public static System.Collections.ArrayList ReadIniSections(string inipath)
        {
            var buffer = new byte[65535];
            var rel = GetPrivateProfileSectionNamesA(buffer, buffer.GetUpperBound(0), inipath);
            var arrayList = new System.Collections.ArrayList();
            if (rel <= 0) return arrayList;
            int iCnt; var iPos = 0;
            for (iCnt = 0; iCnt < rel; iCnt++)
            {
                if (buffer[iCnt] != 0x00) continue;
                var tmp = Encoding.Default.GetString(buffer, iPos, iCnt - iPos).Trim();
                iPos = iCnt + 1;
                if (tmp != "")
                    arrayList.Add(tmp);
            }
            return arrayList;
        }

    }
}